/*
 * Copyright (c) 2020-2021, Bluetrum Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020/12/10     xu    The first version
 */

/**
 * Notice!
 * All functions or data that are called during an interrupt need to be in RAM.
 * You can do it the way exception_isr() does.
 */
#include "EPD_4in2b_V2.h"
#include "EPD_4in2b_V2_test.h"
#include "SPI_RAM.h"
#include "W25Qx.h"
#include "board.h"
#include "key_task.h"
#include "message_type.h"
#include "network_task.h"
#include "ui_task.h"
#include <rtthread.h>

#define MAIN_MQ_MAX_MSGS 128

int main(void)
{
    rt_bool_t retval = RT_FALSE;
    key_task_t key_task = RT_NULL;
    network_task_t net_task = RT_NULL;
    ui_task_t ui_task = RT_NULL;
    rt_kprintf("Hello, world\n");

    rt_mq_t main_mq = rt_mq_create("main_mq", sizeof(struct message), MAIN_MQ_MAX_MSGS, RT_IPC_FLAG_FIFO);
    rt_kprintf("create main mq %s!\n", main_mq ? "OK" : "FAIL");

    ui_task = ui_task_create();
    retval = ui_task_start(ui_task);
    rt_kprintf("create ui task %s!\n", ui_task ? "OK" : "FAIL");
    rt_kprintf("start ui task %s!\n", retval ? "OK" : "FAIL");

    key_task = key_task_create(main_mq, 50);
    retval = key_task_start(key_task);
    rt_kprintf("create key task %s!\n", key_task ? "OK" : "FAIL");
    rt_kprintf("start key task %s!\n", retval ? "OK" : "FAIL");

    net_task = network_task_create(main_mq);
    retval = network_task_start(net_task);
    rt_kprintf("create network task %s\n", net_task ? "OK" : "FAIL");
    rt_kprintf("start network task %s\n", retval ? "OK" : "FAIL");

    rt_thread_mdelay(12000); // wait for network ready
    network_task_control(net_task, NETWORK_TIME_SYNC);
    ui_task_control(ui_task, VIEW_MONTHLY);

    const rt_tick_t refresh_ticks = rt_tick_from_millisecond(120*1000);
    while (1) {
        struct message event = {0};
        rt_err_t err = rt_mq_recv(main_mq, &event, sizeof(event), refresh_ticks);
        if (err != RT_EOK) {
            rt_kprintf("recv mq failed!\n");
            continue;
        } else if (err == RT_ETIMEOUT) {
            rt_kprintf("recv mq timeout, refresh display...\n");
            ui_task_control(ui_task, VIEW_MONTHLY);
        }

        if (event.type == MSG_KEY_EVENT) {
            const struct key_event key_event = event.data.key_event;
            rt_kprintf("Got key event: key = %d, state = %s\n", key_event.key,
                       key_event.state == STATE_PRESSED ? "PRESSED" : "RELEASE");
            if ((key_event.key == ID_KEY1) && (key_event.state == STATE_PRESSED)) {
                ui_task_control(ui_task, VIEW_MONTHLY);
            } else if ((key_event.key == ID_KEY2) && (key_event.state == STATE_PRESSED)) {
                network_task_control(net_task, NETWORK_TIME_SYNC);
            } else if ((key_event.key == ID_KEY3) && (key_event.state == STATE_PRESSED)) {
                network_task_control(net_task, NETWORK_CN_DATE_GET);
            }
        }
    }
}
